using System;
using System.Collections.Generic;

namespace CoreRay
{
	//-------------------------------------------------------------------------------------
	/// <summary>
	/// Class that manages the logging system.
	/// </summary>
	//-------------------------------------------------------------------------------------

	public class LogManager : IDisposable
	{
		//-------------------------------------------------------------------------------------
		// Private member.
		//-------------------------------------------------------------------------------------

		private List<LogReceiver> logReceivers;


		//-------------------------------------------------------------------------------------
		/// <summary>
		/// Default constructor.
		/// </summary>
		//-------------------------------------------------------------------------------------

		public LogManager()
		{
			this.logReceivers = new List<LogReceiver>();
		}


		//-------------------------------------------------------------------------------------
		/// <summary>
		/// Adds a log receiver to the log receivers list that will receive all logging
		/// informations.
		/// </summary>
		/// <param name="logReceiver">Log receiver to add to the list.</param>
		//-------------------------------------------------------------------------------------

		public void AddLogReceiver(LogReceiver logReceiver)
		{
			if(!this.logReceivers.Contains(logReceiver))
			{
				this.logReceivers.Add(logReceiver);
			}
		}


		//-------------------------------------------------------------------------------------
		/// <summary>
		/// Disposes all the log receivers that implement the IDispose interface.
		/// </summary>
		//-------------------------------------------------------------------------------------

		public void Dispose()
		{
            this.Dispose(true);
		}


        protected virtual void Dispose(bool isDisposing)
        {
            if(this.logReceivers != null)
            {
                //Dispose log receivers
                foreach(LogReceiver logReceiver in this.logReceivers)
                {
                    IDisposable disposableObject = logReceiver as IDisposable;

                    if(disposableObject != null)
                    {
                        disposableObject.Dispose();
                    }
                }

                //Set private member reference to null
                this.logReceivers = null;
            }
        }


		//-------------------------------------------------------------------------------------
		/// <summary>
		/// Writes a log information message with formatting.
		/// </summary>
		/// <param name="message">Formatted Message to write.</param>
		/// <param name="arguments">Parameters for the formatting of the message.</param>
		//-------------------------------------------------------------------------------------

		public void Write(string message, params object[] arguments)
		{
			this.Write(LogInformationTypes.Information, "General", message, arguments);
		}


		//-------------------------------------------------------------------------------------
		/// <summary>
		/// Writes a log message with the specified information type with formatting.
		/// </summary>
		/// <param name="informationType">Information type.</param>
		/// <param name="message">Message to write.</param>
		/// <param name="arguments">Parameters for the formatting of the message.</param>
		//-------------------------------------------------------------------------------------

		public void Write(LogInformationTypes informationType, string message, params object[] arguments)
		{
			this.Write(informationType, "General", message, arguments);
		}


		//-------------------------------------------------------------------------------------
		/// <summary>
		/// Writes a log message with the specified information type with formatting.
		/// </summary>
		/// <param name="message">Message to write.</param>
		/// <param name="category">Category of the message.</param>
		/// <param name="arguments">Parameters for the formatting of the message.</param>
		//-------------------------------------------------------------------------------------

		public void Write(string category, string message, params object[] arguments)
		{
			this.Write(LogInformationTypes.Information, category, message, arguments);
		}


		//-------------------------------------------------------------------------------------
		/// <summary>
		/// Writes a log message with the specified information type with formatting.
		/// </summary>
		/// <param name="informationType">Information type.</param>
		/// <param name="message">Message to write.</param>
		/// <param name="category">Category of the message.</param>
		/// <param name="arguments">Parameters for the formatting of the message.</param>
		//-------------------------------------------------------------------------------------

		public void Write(LogInformationTypes informationType, string category, string message, params object[] arguments)
		{
			string fullMessage = string.Format(message, arguments);

			if(informationType != LogInformationTypes.All && this.logReceivers != null)
			{
				foreach(LogReceiver logReceiver in this.logReceivers)
				{
					if((logReceiver.InformationType & informationType) != 0)
					{
						logReceiver.Write(fullMessage, category, informationType);
					}
				}
			}
		}
	}
}
